﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Net.Http;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Office.Core;
using Microsoft.Office.Interop.Excel;
using Newtonsoft.Json.Linq;
using Excel = Microsoft.Office.Interop.Excel;

namespace ExcelCOMAddin
{
    [ComVisible(true)]
    [Guid("EED7B05F-08A0-44FA-AC5B-D8FC832D1BA1")]// 替换为实际GUID
    [ProgId("EastMoneyRTD.RTDServer")] 
    public class RTDServer : IRtdServer
    {
        private static readonly HttpClient _httpClient = CreateHttpClient();
        private IRTDUpdateEvent _callback;
        private readonly ConcurrentDictionary<int, (string Symbol, string Field)> _topics = new();
        private readonly ConcurrentDictionary<int, object> _values = new();
        private readonly ConcurrentDictionary<int, DateTime> _timestamps = new();
        private const int CacheDurationInSeconds = 300; // 缓存5分钟

        // 创建HTTP客户端
        private static HttpClient CreateHttpClient()
        {
            var handler = new HttpClientHandler
            {
                AutomaticDecompression = System.Net.DecompressionMethods.GZip | System.Net.DecompressionMethods.Deflate
            };

            // 设置ServicePointManager的连接限制（全局设置）
            System.Net.ServicePointManager.DefaultConnectionLimit = Environment.ProcessorCount * 4;

            return new HttpClient(handler)
            {
                Timeout = TimeSpan.FromSeconds(10),
            };
        }

        // IRtdServer 实现
        public int ServerStart(IRTDUpdateEvent CallbackObject)
        {
            _callback = CallbackObject;
            return 1; // 线程ID
        }

        public void ServerTerminate()
        {
            _callback = null;
        }

        public object ConnectData(int TopicID, ref Array Strings, ref bool GetNewValues)
        {
            if (Strings.Length < 2)
                return "Invalid Parameters";

            string symbol = Strings.GetValue(0).ToString();
            string field = Strings.GetValue(1).ToString();

            _topics[TopicID] = (symbol, field);

            // 检查缓存
            if (_values.TryGetValue(TopicID, out object cachedValue) &&
                DateTime.Now - GetValueOrDefault(_timestamps, TopicID, DateTime.MinValue) < TimeSpan.FromSeconds(CacheDurationInSeconds))
            {
                return cachedValue;
            }

            // 异步获取数据
            Task.Run(() => UpdateDataAsync(TopicID, symbol, field));

            // 返回初始值
            return "Loading..";
        }

        public DateTime GetValueOrDefault(ConcurrentDictionary<int, DateTime> dictionary, int key, DateTime defaultValue = default)
        {
            return dictionary.TryGetValue(key, out DateTime value) ? value : defaultValue;
        }
        public void DisconnectData(int TopicID)
        {
            _topics.TryRemove(TopicID, out _);
            _values.TryRemove(TopicID, out _);
            _timestamps.TryRemove(TopicID, out _);
        }

        public int Heartbeat()
        {
            return 1;
        }

        public Array RefreshData(ref int TopicCount)
        {
            TopicCount = 0;
            return null;
        }

        private async void UpdateDataAsync(int topicID, string symbol, string field)
        {
            try
            {
                string url = $"https://push2.eastmoney.com/api/qt/clist/get?np=1&fltt=1&invt=2&fs=m%3A90%2Bt%3A2&fields=f14%2Cf12%2Cf13%2Cf62%2Cf204%2Cf205%2Cf206&fid=f62&pn=1&pz=5&po=1&ut=fa5fd1943c7b386f172d6893dbfba10b&dect=1&wbp2u=1794097457367022%7C0%7C1%7C0%7Cweb&_=1745892478165";
                var response = await _httpClient.GetAsync(url);
                response.EnsureSuccessStatusCode();
                string content = await response.Content.ReadAsStringAsync();

                object value = ParseJson(content, field);

                // 更新缓存
                if (!_values.ContainsKey(topicID))
                {
                    _values[topicID] = value;
                    _timestamps[topicID] = DateTime.Now;
                }
                else
                {
                    _values[topicID] = value;
                    _timestamps[topicID] = DateTime.Now;
                }

                // 通知Excel更新
                _callback.UpdateNotify();
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error fetching data for Topic {topicID}: {ex.Message}");
            }
        }

        private object ParseJson(string json, string field)
        {
            try
            {
                var jsonObject = Newtonsoft.Json.Linq.JObject.Parse(json);
                if (field == "svr")
                    return jsonObject["svr"]?.Value<decimal?>() ?? 0m;
                if (field == "volume")
                    return jsonObject["volume"]?.Value<long?>() ?? 0L;
                if (field == "amount")
                    return jsonObject["amount"]?.Value<decimal?>() ?? 0m;
                if (field == "open")
                    return jsonObject["open"]?.Value<decimal?>() ?? 0m;
                if (field == "close")
                    return jsonObject["close"]?.Value<decimal?>() ?? 0m;
                // 添加更多字段的解析
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error parsing JSON: {ex.Message}");
            }
            return null;
        }
    }

    // 注意：GetValueOrDefault 不是 ConcurrentDictionary 的内置方法，我们不需要它
    // 如果需要，可以创建扩展方法，但在本例中不需要
}